﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows.Input;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace Sai_Se_Dung
{
    public class DataModel : INotifyPropertyChanged
    {
        public ObservableCollection<Data> m_items { get; private set; }
        private CommandHandler m_ansCommand;
        private CommandHandler m_btnCommand;
        private Data m_curData;

        public bool m_isCorrectAnswer = false;
        private string m_curPlayerAnswer = "";
        private int m_index = 1;

        private int m_curIndex = 1; // Set milestone for Level 3

        #region Show on Screen - View
        // Hiển thị màn chơi
        public string Level { get { return Play.m_level == 0 ? "1" : Play.m_level.ToString(); } }
        // Hiển thị số câu hỏi
        public string QNum { get { return Play.m_num == 0 ? "1" : Play.m_num.ToString(); } }
        //Hiển thị điểm số
        public string Score { get { return Play.m_score.ToString(); } }
        // Load đáp án lên màn hình
        private string[] Temp = { "", "" };
        public string A { get { return "A: " + Temp[0]; } }
        public string B { get { return "B: " + Temp[1]; } }
        // Load câu hỏi lên màn hình
        public string Question { get { return (m_curData != null ? m_curData.Q : " "); } }
        #endregion

        #region Command Handler
        /// <summary>
        /// Answer Command Handler
        /// </summary>
        public ICommand AnswerCommand
        {
            get
            {
                if (m_ansCommand == null)
                    m_ansCommand = new CommandHandler(new Action<object>((object param) =>
                    CheckGameLogic(param)), new Func<object, bool>((object _param) =>
                    {
                        // optionally provide feedback to the control
                        // as to the state of this command.
                        return true;
                    }));

                return m_ansCommand;
            }
        }

        /// <summary>
        /// Button Command Handler
        /// </summary>
        public ICommand ButtonCommand
        {
            get
            {
                if (m_btnCommand == null)
                    m_btnCommand = new CommandHandler(new Action<object>((object param) =>
                    {
                        if ((param as string).Equals("Tiếp tục"))
                        {
                            // Test for button command
                            //Index++;
                        }

                    }), new Func<object, bool>((object parm) =>
                    {

                        // optionally provide feeback to the control
                        // as to the state of this command.
                        return true;
                    }));

                return m_btnCommand;
            }
        }
        #endregion

        /// <summary>
        /// Constructor
        /// </summary>
        public DataModel()
        {
            m_items = new ObservableCollection<Data>();
        }

        public void PlayCorrectSound()
        {
            if (Option.isOn == true)
            {
                Sound.PlaySound("SoundEffect/correct_sound.wav");
            }
        }

        public void PlayWrongSound()
        {
            if (Option.isOn == true)
            {
                Sound.PlaySound("SoundEffect/wrong_sound.wav");
            }
        }

        /// <summary>
        /// Lấy câu trả lời để kiểm tra
        /// </summary>
        /// <param name="_answer"></param>
        /// <returns></returns>
        private string GetAnswer(string _answer)
        {
            return _answer == "A" ? m_curData.A : m_curData.B;
        }

        /// <summary>
        /// Kiểm tra logic game
        /// </summary>
        /// <param name="param"></param>
        private void CheckGameLogic(object param)
        {
            m_curPlayerAnswer = (param as string).Substring(3);
            m_isCorrectAnswer = m_curPlayerAnswer.Equals(GetAnswer(m_curData.R));

            #region Logic Data Model
            //-------------------------------------------------------------------------------------
            /// <Trả lời đúng>
            // nếu đang ở màn 1, score += 10;
            // nếu đang ở màn 2, score += m_num * 10;
            // nếu đang ở màn 3, score += 100;
            // ------------------------------------------------------------------------------------
            /// <Trả lời sai>
            // nếu đang ở màn 1, còn thời gian thì cho chơi tiếp, trả lời sai quá 5 câu, game over
            // đang ở màn 2, game over
            // đang ở màn 3, quay lại câu 1, hết thời gian, trừ dần điểm, điểm về 0, game over
            //-------------------------------------------------------------------------------------

            switch (Play.m_level)
            {
                // Màn 1 --------------------------------------------------------------------------------
                case 1:
                    if (Play.m_time >= 0)
                    {
                        // Trả lời đúng
                        if (m_isCorrectAnswer == true)
                        {
                            Play.m_score += 10; // Cộng điểm
                            PlayCorrectSound();
                        }
                        else // Trả lời sai
                        {
                            PlayWrongSound();
                        }

                        // Trả lời sai quá 5 câu
                        if ((Play.m_num - (Play.m_score / 10)) > 5)
                        {
                            Play.m_isEnded = true;
                        }
                        else
                        {
                            Play.m_num++; // Tăng số câu hỏi
                            Index++; // Đổi câu hỏi
                        }
                    }
                    break;

                // Màn 2 --------------------------------------------------------------------------------
                case 2:
                    if (Play.m_time >= 0)
                    {
                        if (m_isCorrectAnswer == true) // Trả lời đúng
                        {
                            PlayCorrectSound();
                            Play.m_score += Play.m_num * 10;

                            if (Play.m_num < 10)
                            {
                                Play.m_time = 6;
                                Play.m_num++;
                                Index++;
                            }
                            else
                            {
                                Play.m_isNextLevel = true; // Next level
                                // Lấy cái index hiện tại để làm mốc quay lại cho level 3
                                Index++;
                                m_curIndex = Index;
                            }
                        }
                        else
                        { // Trả lời sai
                            PlayWrongSound();
                            Play.m_isEnded = true;
                        }
                    }
                    break;

                // Màn 3 --------------------------------------------------------------------------------
                case 3:
                    if (m_isCorrectAnswer == true) // Trả lời đúng
                    {
                        PlayCorrectSound();
                        Play.m_score += 100;
                        if (Play.m_num < 15)
                        {
                            Play.m_num++;
                            Index++;
                        }
                        else
                        {
                            Play.m_isWinned = true;
                        }
                    }
                    else // Trả lời sai
                    {
                        PlayWrongSound();
                        Play.m_score -= (Play.m_num - 1) * 100;
                        Play.m_num = 1;
                        // Quay về câu đầu tiên của màn 3
                        Index = m_curIndex;
                    }
                    break;
            }
            #endregion
        }

        /// <summary>
        /// Đổi câu hỏi, đáp án
        /// </summary>
        public int Index
        {
            get { return m_index; }
            set
            {
                m_index = value;

                #region Hết câu hỏi trong Question.xml - Trường hợp không bao giờ xảy ra =))
                if (m_index - 1 == m_items.Count)
                {
                    m_index = 1;
                }
                #endregion

                m_curData = m_items[Index - 1];
                List<string> t = new List<string>();
                t.Add(m_curData.A);
                t.Add(m_curData.B);
                Shuffle(t); // Đổi nội dung đáp án A <--> B
                Temp = t.ToArray();

                NotifyPropertyChanged("Question");
                NotifyPropertyChanged("A");
                NotifyPropertyChanged("B");
                NotifyPropertyChanged("QNum");
                NotifyPropertyChanged("Level");
                NotifyPropertyChanged("Score");
            }
        }

        /// <summary>
        /// Thay đổi giá trị thuộc tính
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Đọc câu hỏi từ file Question.xml
        /// </summary>
        public void LoadData()
        {
            XDocument xdoc = XDocument.Load(string.Format("Question.xml"));
            var data = from query in xdoc.Element("Datas").Elements("Data")
                       select new Data
                       {
                           Q = (string)query.Element("Q"),
                           A = (string)query.Element("A"),
                           B = (string)query.Element("B"),
                           R = ((string)query.Element("R")).Trim()
                       };
            m_items.Clear();
            foreach (var item in data)
            {
                m_items.Add(item);
            }
            Shuffle(m_items);
            m_curData = m_items[m_index - 1];
            Index = 1;
        }

        /// <summary>
        /// Xáo trộn các câu hỏi
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        public static void Shuffle<T>(IList<T> list)
        {
            var random = new Random(DateTime.Now.Millisecond);
            var n = list.Count;
            while (n > 1)
            {
                n--;
                var k = random.Next(n + 1);
                var value = list[k];
                list[k] = list[n];
                list[n] = value;
            }
        }

        /// ----------------------------------------------------------------------
        #region Level 3 - Bựa chút thôi
        ///// <summary>
        ///// Đổi câu hỏi, đáp án cho level 3
        ///// </summary>
        //public int IndexLv3
        //{
        //    get { return lv3_index; }
        //    set
        //    {
        //        lv3_index = value;

        //        if (lv3_index - 1 == 15)
        //        {
        //            lv3_index = 1;
        //        }

        //        m_curData = lv3_items[IndexLv3 - 1]; // Lấy từ phần từ đầu tiên
        //        List<string> t = new List<string>();
        //        t.Add(m_curData.A);
        //        t.Add(m_curData.B);
        //        Shuffle(t);
        //        Temp = t.ToArray();

        //        NotifyPropertyChanged("Question");
        //        NotifyPropertyChanged("A");
        //        NotifyPropertyChanged("B");
        //        NotifyPropertyChanged("QNum");
        //        NotifyPropertyChanged("Level");
        //        NotifyPropertyChanged("Score");
        //    }
        //}
        
        ///// <summary>
        ///// Load 15 câu hỏi cho màn 3
        ///// </summary>
        //public void LoadDataForLevel3()
        //{
        //    XDocument xdoc = XDocument.Load(string.Format("Question.xml"));
        //    var data = from query in xdoc.Element("Datas").Elements("Data")
        //               select new Data
        //               {
        //                   Q = (string)query.Element("Q"),
        //                   A = (string)query.Element("A"),
        //                   B = (string)query.Element("B"),
        //                   R = ((string)query.Element("R")).Trim()
        //               };
        //    lv3_items.Clear();
        //    foreach (var item in data)
        //    {
        //        lv3_items.Add(item);
        //    }
        //    //Shuffle(lv3_items);
        //    m_curData = lv3_items[lv3_index - 1];
        //    IndexLv3 = 1;
        //}
        #endregion

    }
}
